package com.alibaba.citrus.cr.mn.order.center.facade.function.check;

import com.alibaba.citrus.cr.common.enums.ordercenter.*;
import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.common.util.DateUtils;
import com.alibaba.citrus.cr.mn.order.center.common.util.AssertUtils;
import com.alibaba.citrus.cr.mn.order.center.common.util.JsonUtils;
import com.alibaba.citrus.cr.mn.order.center.common.util.MoneyUtils;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.BaseDataServiceAdapter;
import com.epoch.app.mnordercenter.model.dto.DictionaryResponse;
import com.epoch.app.mnordercenter.model.dto.SalesOrderAtomCreateLineRequest;
import com.epoch.app.mnordercenter.model.dto.SalesOrderAtomCreateRequest;
import com.epoch.app.mnordercenter.orderbaserequest.OrderAtomCreateResponse;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zhangxiaorui
 * @ClassName SalesOrderCreateParamsCheck
 * @description: TODO
 * @date 2023/05/11 16:35
 * @version: 1.0
 */
@Service
public class SalesOrderCreateParamsCheck extends AbstractOrderParamsCheckService<SalesOrderAtomCreateRequest, OrderAtomCreateResponse> {

    @Resource
    private BaseDataServiceAdapter baseDataServiceAdapter;


    @Override
    public void paramsEnumDictCheck(List<SalesOrderAtomCreateRequest> requestList, List<OrderAtomCreateResponse> responseList){

        List<DictionaryResponse> fromSysResponseList = baseDataServiceAdapter.queryDictionarys(DictionaryTypeEnum.FROM_SYS.getCode());
        Map<String, DictionaryResponse> fromSysMap = fromSysResponseList.stream().collect(Collectors.toMap(DictionaryResponse::getCode, Function.identity(), (k1, k2) -> k2));
        //业态
        List<DictionaryResponse> businessTypeResponseList = baseDataServiceAdapter.queryDictionarys(DictionaryTypeEnum.BUSINESS_TYPE.getCode());
        Map<String, DictionaryResponse> businessTypeMap = businessTypeResponseList.stream().collect(Collectors.toMap(DictionaryResponse::getCode, Function.identity(), (k1, k2) -> k2));

        requestList.forEach(t->{

            if (fromSysMap.get(t.getFromSys()) == null) {
                throw new FunctionException("OC-01-001-01-15-006", "来源系统编码");
            }
            DictionaryResponse dictionaryResponse = businessTypeMap.get(t.getBusinessType());
            if (dictionaryResponse == null) {
                throw new FunctionException("OC-01-001-01-15-006", "业态编码");
            }
            // 覆盖用户传入数据
            t.setBusinessTypeName(dictionaryResponse.getName());

            SalesOrderTypeEnum salesOrderTypeEnum = SalesOrderTypeEnum.of(t.getSalesOrderType());
            Optional.ofNullable(salesOrderTypeEnum).orElseThrow(() -> new FunctionException("OC-01-001-01-15-006", "订单类型编码"));
            // 覆盖用户传入数据
            t.setSalesOrderTypeName(salesOrderTypeEnum.getDesc());

            SalesOrderDeliveryMethodEnum salesOrderDeliveryMethodEnum = SalesOrderDeliveryMethodEnum.of(t.getDeliveryMethodCode());
            Optional.ofNullable(salesOrderDeliveryMethodEnum).orElseThrow(() -> new FunctionException("OC-01-001-01-15-006", "配送方式编码"));
            // 覆盖用户传入数据
            t.setDeliveryMethodName(salesOrderDeliveryMethodEnum.getDesc());

            if(StringUtils.isNotBlank(t.getOrderReasonCode())){
                SalesOrderReasonEnum salesOrderReasonEnum = SalesOrderReasonEnum.of(t.getOrderReasonCode());
                Optional.ofNullable(salesOrderReasonEnum).orElseThrow(() -> new FunctionException("OC-01-001-01-15-006", "订单原因编码"));
            }

            // 校验扩展字段是否为JSON格式
            AssertUtils.isTrue(!JsonUtils.isValidJson(t.getBizFeatures()), "OC-00-001-01-15-001", "扩展字段");

            for (SalesOrderAtomCreateLineRequest p : t.getOrderDetails()) {
                StockUnitEnum salesUnit = StockUnitEnum.of(p.getSalesUnitCode());
                StockUnitEnum stockUnit = StockUnitEnum.of(p.getStockUnitCode());
                Optional.ofNullable(salesUnit).orElseThrow(() -> new FunctionException("OC-01-001-01-15-006", "销售单位编码"));
                Optional.ofNullable(stockUnit).orElseThrow(() -> new FunctionException("OC-01-001-01-15-006", "库存单位编码"));

                // 覆盖用户传入数据
                p.setSalesUnitName(salesUnit.getDesc());
                p.setStockUnitName(stockUnit.getDesc());

                // 校验扩展字段是否为JSON格式
                AssertUtils.isTrue(!JsonUtils.isValidJson(p.getBizFeatures()), "OC-00-001-01-15-001", "扩展字段");
            }
        });
    }

    @Override
    public void paramsNotBlankCheck(List<SalesOrderAtomCreateRequest> requestList, List<OrderAtomCreateResponse> responseList) {
        AssertUtils.isTrue(CollectionUtils.isEmpty(requestList), "OC-01-001-01-15-001", "单据列表");
        AssertUtils.isTrue(requestList.size() > 100, "OC-01-001-01-15-004", "单据列表", requestList.size(), "100");
        requestList.forEach(t -> {
            // 必填校验
            AssertUtils.isTrue(StringUtils.isBlank(t.getFromSys()),              "OC-01-001-01-15-001", "来源系统编码");
            AssertUtils.isTrue(StringUtils.isBlank(t.getBusinessType()),         "OC-01-001-01-15-001", "业态编码");
            AssertUtils.isTrue(StringUtils.isBlank(t.getBusinessUnitCode()),     "OC-01-001-01-15-001", "业务单元编码");
            AssertUtils.isTrue(StringUtils.isBlank(t.getSourceOrderNo()),        "OC-01-001-01-15-001", "来源单号");
            AssertUtils.isTrue(StringUtils.isBlank(t.getExpectedDeliveryDate()), "OC-01-001-01-15-001", "期望交货日期");

            //AssertUtils.isTrue(StringUtils.isBlank(t.getPreOrderNo()), "OC-01-001-01-15-001", "业务单元编码");
            AssertUtils.isTrue(StringUtils.isBlank(t.getBusinessUnitCode()), "OC-01-001-01-15-001", "业务单元编码");
            //AssertUtils.isTrue(Objects.isNull(t.getIsSubmit()), "OC-01-001-01-15-001", "是否提交");
            AssertUtils.isTrue(StringUtils.isBlank(t.getSalesOrderType()), "OC-01-001-01-15-001", "订单类型编码");
            //AssertUtils.checkRequired(Pair.of(t.getSalesOrderType(), t.getSalesOrderTypeName()),            "OC-01-001-01-15-001", "订单类型编码、名称(都)");
            AssertUtils.checkRequired(Pair.of(t.getCustomerCode(), t.getCustomerName()),                    "OC-01-001-01-15-001", "客户售达方编码、名称(都)");
            AssertUtils.checkRequired(Pair.of(t.getShipToPartyCode(), t.getShipToPartyName()),              "OC-01-001-01-15-001", "客户送达方编码、名称(都)");
            AssertUtils.checkRequired(Pair.of(t.getBusinessChannel(), t.getBusinessChannelName()),          "OC-01-001-01-15-001", "业务渠道编码、名称(都)");
            AssertUtils.checkRequired(Pair.of(t.getSalesOrganizationCode(), t.getSalesOrganizationName()),  "OC-01-001-01-15-001", "销售组织编码、名称(都)");
            AssertUtils.checkRequired(Pair.of(t.getProductGroupCode(), t.getProductGroupName()),            "OC-01-001-01-15-001", "产品组编码、名称(都)");
            AssertUtils.isTrue(StringUtils.isBlank(t.getDeliveryMethodCode()), "OC-01-001-01-15-001", "配送方式编码");
            //AssertUtils.checkRequired(Pair.of(t.getDeliveryMethodCode(), t.getDeliveryMethodName()),        "OC-01-001-01-15-001", "配送方式编码、名称(都)");
            AssertUtils.checkRequired(Pair.of(t.getCreatorCode(), t.getCreatorName()),                      "OC-01-001-01-15-001", "创建人工号、姓名(都)");

            // 非必填校验，若填写需保证成对存在
            //AssertUtils.checkNotRequired(Pair.of(t.getSalesChannelCode(), t.getSalesChannelName()),            "OC-01-001-01-15-001", "销售渠道编码、名称(其一)");
            //AssertUtils.checkNotRequired(Pair.of(t.getSalesDepartmentCode(), t.getSalesDepartmentName()),      "OC-01-001-01-15-001", "销售部门编码、名称(其一)");
            //AssertUtils.checkNotRequired(Pair.of(t.getCostCenterCode(), t.getCostCenterName()),                "OC-01-001-01-15-001", "成本中心编码、名称(其一)");
            //AssertUtils.checkNotRequired(Pair.of(t.getOrderReasonCode(), t.getOrderReasonCode()),              "OC-01-001-01-15-001", "订单原因编码、名称(其一)");

            AssertUtils.isTrue(CollectionUtils.isEmpty(t.getOrderDetails()), "OC-01-001-01-15-001", "单据明细");
            AssertUtils.isTrue(t.getOrderDetails().size() > 100, "OC-01-001-01-15-004", "单据明细", t.getOrderDetails().size(), "100");
            t.getOrderDetails().forEach(detail -> {
                AssertUtils.isTrue(StringUtils.isBlank(detail.getSourceLineNum()),              "OC-01-001-01-15-001", "来源单行号");
                AssertUtils.isTrue(StringUtils.isBlank(detail.getProductQuantity()),            "OC-01-001-01-15-001", "销售数量");
                AssertUtils.isTrue(StringUtils.isBlank(detail.getStockConversionNum()),         "OC-01-001-01-15-001", "库存转换数量");
                AssertUtils.isTrue(StringUtils.isBlank(detail.getUnitConversionRelationship()), "OC-01-001-01-15-001", "单位转换关系");
                AssertUtils.isTrue(StringUtils.isBlank(detail.getUnitPrice()),                  "OC-01-001-01-15-001", "常规单价");
                AssertUtils.isTrue(StringUtils.isBlank(detail.getTotalAmount()),                "OC-01-001-01-15-001", "常规总金额");

                //AssertUtils.check(Pair.of(detail.getInnerProductCode(), detail.getInnerProductName()),           "OC-01-001-01-15-001", "产品编码、名称(都)");
                AssertUtils.checkRequired(Pair.of(detail.getProductCode(), detail.getProductName()),                     "OC-01-001-01-15-001", "物料编码、名称(都)");
                AssertUtils.checkRequired(Pair.of(detail.getSalesUnitCode(), detail.getSalesUnitName()),                 "OC-01-001-01-15-001", "销售单位编码、名称(都)");
                AssertUtils.checkRequired(Pair.of(detail.getStockUnitCode(), detail.getStockUnitName()),                 "OC-01-001-01-15-001", "库存单位编码、名称(都)");

                // 非必填校验，若填写需保证成对存在
                AssertUtils.checkNotRequired(Pair.of(detail.getShippingWarehouseCode(), detail.getShippingWarehouseName()), "OC-01-001-01-15-001", "逻辑仓库编码、名称(其一)");
                //AssertUtils.checkNotRequired(Pair.of(detail.getDeliveryFactoryCode(), detail.getDeliveryFactoryName()),     "OC-01-001-01-15-001", "交货工厂编码、名称(其一)");
                //AssertUtils.checkNotRequired(Pair.of(detail.getStockCode(), detail.getStockName()),                         "OC-01-001-01-15-001", "库存地点编码、名称(其一)");

                if (StringUtils.isBlank(detail.getShippingWarehouseCode())) {
                    if(StringUtils.isBlank(detail.getDeliveryFactoryCode()) && StringUtils.isBlank(detail.getStockCode())) {
                        throw new FunctionException("OC-01-001-01-15-010", "逻辑仓库编码、交货工厂编码、库存地点编码");
                    }
                    AssertUtils.isTrue(StringUtils.isBlank(detail.getDeliveryFactoryCode()), "OC-01-001-01-15-001", "交货工厂编码");
                    AssertUtils.isTrue(StringUtils.isBlank(detail.getStockCode()), "OC-01-001-01-15-001", "库存地点编码");
                }

                // 现金单据校验 手工单价、手工总金额必填
                if(SalesOrderTypeEnum.CASH_ORDER.equals(SalesOrderTypeEnum.of(t.getSalesOrderType()))) {
                    AssertUtils.isTrue(StringUtils.isBlank(t.getCashCustomerName()),        "OC-01-001-01-15-001", "(销售公司现金销售订单)一次性客户名称");
                    AssertUtils.isTrue(StringUtils.isBlank(detail.getManualTotalAmount()),  "OC-01-001-01-15-001", "(销售公司现金销售订单)手工总金额");
                    AssertUtils.isTrue(StringUtils.isBlank(detail.getManualPrice()),        "OC-01-001-01-15-001", "(销售公司现金销售订单)手工单价");
                }

                // 活动类型明细校验
                if (StringUtils.isNotBlank(detail.getActivityType())) {
                    if (StringUtils.isBlank(detail.getActivityType())) {
                        AssertUtils.isTrue(StringUtils.isBlank(detail.getActivityId()), "OC-01-001-01-15-001", "活动类型");
                    }
                    String[] activityTypeArr = detail.getActivityType().split("/");
                    for (String activityType : activityTypeArr) {
                        SalesOrderActivityTypeEnum activityTypeEnum = SalesOrderActivityTypeEnum.of(activityType);
                        Optional.ofNullable(activityTypeEnum).orElseThrow(() -> new FunctionException("OC-01-001-01-15-006", "活动类型"));
                        AssertUtils.isTrue(StringUtils.isBlank(detail.getActivityId()),        "OC-01-001-01-15-001", "活动类型不空时,活动ID");
                        // 非搭赠活动
                        if(!SalesOrderActivityTypeEnum.TAKE_GIFT.equals(activityTypeEnum)) {
                            AssertUtils.isTrue(StringUtils.isBlank(detail.getActivityLineNo()), "OC-01-001-01-15-001", "活动类型不空时,活动项目号");
                        }
                        // 买赠校验
                        if(SalesOrderActivityTypeEnum.BUY_GIFT.equals(activityTypeEnum)) {
                            AssertUtils.isTrue(StringUtils.isBlank(detail.getGiftFlag()),        "OC-01-001-01-15-001", "活动类型为(买赠)时,买赠标识");
                            AssertUtils.isTrue(StringUtils.isBlank(detail.getBuyItemNo()),       "OC-01-001-01-15-001", "活动类型为(买赠)时,原品行号");
                        }
                    }
                } else {
                    // 活动类型为空时，入参活动ID或活动项目号不为空，报入参非法
                    AssertUtils.isTrue(StringUtils.isNotBlank(detail.getActivityId()), "OC-01-001-01-15-015", "活动类型", "活动ID");
                    AssertUtils.isTrue(StringUtils.isNotBlank(detail.getActivityLineNo()), "OC-01-001-01-15-015", "活动类型", "活动项目号");
                }

                // 活动类型、活动ID、活动项目号 要传全传，要么全不传
//                AssertUtils.checkNotRequired("OC-01-001-01-15-001","活动类型、活动ID、活动项目号", detail.getActivityType(), detail.getActivityId(), detail.getActivityLineNo());
            });

            // 免费订单 校验 成本中心
            if(SalesOrderTypeEnum.FREE_ORDER.equals(SalesOrderTypeEnum.of(t.getSalesOrderType()))) {
                AssertUtils.isTrue(StringUtils.isBlank(t.getCostCenterCode()), "OC-01-001-01-15-001", "(销售公司免费订单)成本中心编码");
                AssertUtils.isTrue(StringUtils.isBlank(t.getCostCenterName()), "OC-01-001-01-15-001", "(销售公司免费订单)成本中心名称");
            }

            // 明细行号不能重复
            List<String> sameSourceLines = t.getOrderDetails().stream().map(SalesOrderAtomCreateLineRequest::getSourceLineNum)
                    .collect(Collectors.toMap(p -> p, p -> 1, Integer::sum))
                    .entrySet().stream().filter(entry -> entry.getValue() > 1)
                    .map(Map.Entry::getKey).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(sameSourceLines)) {
                throw new FunctionException("OC-01-001-01-15-002", "来源单行号", StringUtils.join(sameSourceLines, ","));
            }
        });

        // 重复数据校验 取出重复数据
        List<String> sameSourceOrderNos = requestList.stream().map(SalesOrderAtomCreateRequest::getSourceOrderNo)
                .collect(Collectors.toMap(t -> t, t -> 1, Integer::sum))
                .entrySet().stream().filter(entry -> entry.getValue() > 1)
                .map(Map.Entry::getKey).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(sameSourceOrderNos)) {
            throw new FunctionException("OC-01-001-01-15-002", "来源单号", StringUtils.join(sameSourceOrderNos, ","));
        }
    }

    @Override
    public void paramsLengthCheck(List<SalesOrderAtomCreateRequest> requestList, List<OrderAtomCreateResponse> responseList) {
        requestList.forEach(t -> {
            // 必填校验
            AssertUtils.lengthCheck(t.getFromSys() ,         50, true,  "OC-01-001-01-15-004", "来源系统编码");
            AssertUtils.lengthCheck(t.getBusinessType(),     10, true,  "OC-01-001-01-15-004", "业态编码");
            AssertUtils.isNumber(t.getBusinessType(), true, "OC-01-001-01-15-006", "业态编码");
            AssertUtils.lengthCheck(t.getBusinessUnitCode(), 50, true,  "OC-01-001-01-15-004", "业务单元编码");
            AssertUtils.lengthCheck(t.getSourceOrderNo(),    50, true,  "OC-01-001-01-15-004", "来源单号");
            AssertUtils.lengthCheck(t.getPreOrderNo(),       50, false, "OC-01-001-01-15-004", "业务单元编码");
            AssertUtils.lengthCheck(t.getOriginalOrderNo(), 50, false, "OC-01-001-01-15-004", "原销售订单单号");
            AssertUtils.lengthCheck(t.getCustomerPurchaseOrderNo(), 50, false, "OC-01-001-01-15-004", "客户采购订单号");

            AssertUtils.lengthCheck(t.getSalesOrderType() ,       10, true,  "OC-01-001-01-15-004", "订单类型编码");
            AssertUtils.lengthCheck(t.getSalesOrderTypeName(),    50, false,  "OC-01-001-01-15-004", "订单类型名称");
            AssertUtils.lengthCheck(t.getCustomerCode(),          50, true,  "OC-01-001-01-15-004", "客户售达方编码");
            AssertUtils.lengthCheck(t.getCustomerName(),          50, true,  "OC-01-001-01-15-004", "客户售达方名称");
            AssertUtils.lengthCheck(t.getShipToPartyCode(),       50, true,  "OC-01-001-01-15-004", "客户送达方编码");
            AssertUtils.lengthCheck(t.getShipToPartyName(),       50, true,  "OC-01-001-01-15-004", "客户送达方名称");
            AssertUtils.lengthCheck(t.getBusinessChannel(),       50, true,  "OC-01-001-01-15-004", "业务渠道编码");
            AssertUtils.lengthCheck(t.getBusinessChannelName(),   50, true,  "OC-01-001-01-15-004", "业务渠道名称");
            AssertUtils.lengthCheck(t.getSalesOrganizationCode(), 50, true,  "OC-01-001-01-15-004", "销售组织编码");
            AssertUtils.lengthCheck(t.getSalesOrganizationName(), 50, true,  "OC-01-001-01-15-004", "销售组织名称");
            AssertUtils.lengthCheck(t.getProductGroupCode(),      50, true,  "OC-01-001-01-15-004", "产品组编码");
            AssertUtils.lengthCheck(t.getProductGroupName(),      50, true,  "OC-01-001-01-15-004", "产品组名称");
            AssertUtils.lengthCheck(t.getDeliveryMethodCode(),    50, true,  "OC-01-001-01-15-004", "配送方式编码");
            AssertUtils.lengthCheck(t.getDeliveryMethodName(),    50, false,  "OC-01-001-01-15-004", "配送方式名称");
            AssertUtils.lengthCheck(t.getCreatorCode(),           50, true,  "OC-01-001-01-15-004", "创建人工号");
            AssertUtils.lengthCheck(t.getCreatorName(),           50, true,  "OC-01-001-01-15-004", "创建人姓名");

            // 非必填校验，若填写需保证成对存在
            AssertUtils.lengthCheck(t.getSalesChannelCode(),    50, false, "OC-01-001-01-15-004", "销售渠道编码");
            AssertUtils.lengthCheck(t.getSalesChannelName(),    50, false, "OC-01-001-01-15-004", "销售渠道名称");
            AssertUtils.lengthCheck(t.getSalesDepartmentCode(), 50, false, "OC-01-001-01-15-004", "销售部门编码");
            AssertUtils.lengthCheck(t.getSalesDepartmentName(), 50, false, "OC-01-001-01-15-004", "销售部门名称");
            AssertUtils.lengthCheck(t.getCostCenterCode(),      50, false, "OC-01-001-01-15-004", "成本中心编码");
            AssertUtils.lengthCheck(t.getCostCenterName(),      50, false, "OC-01-001-01-15-004", "成本中心名称");
            AssertUtils.lengthCheck(t.getOrderReasonCode(),     32, false, "OC-01-001-01-15-004", "订单原因编码");
            AssertUtils.lengthCheck(t.getNote(),               255, false, "OC-01-001-01-15-004", "订单头备注");
            AssertUtils.lengthCheck(t.getCashCustomerName(),    50, false, "OC-01-001-01-15-004", "一次性客户名称");

            AssertUtils.lengthCheck(t.getExpectedDeliveryDate(),    10, true,  "OC-01-001-01-15-004", "期望交货日期");
            AssertUtils.lengthCheck(t.getCustomerPurchaseDate(),    10, false, "OC-01-001-01-15-004", "客户采购订单日期");

            AssertUtils.lengthCheck(t.getBizFeatures(), 1024, false, "OC-01-001-01-15-004", "扩展字段");

            // 日期格式校验
            AssertUtils.isTrue(!DateUtils.isDateFormat(t.getExpectedDeliveryDate()),     "OC-01-001-01-15-006", "期望交货日期");
            // AssertUtils.isTrue(DateUtils.formatDate(new Date()).compareTo(t.getExpectedDeliveryDate()) > 0, "OC-01-001-01-16-021");
            if(StringUtils.isNotBlank(t.getCustomerPurchaseDate())) {
                AssertUtils.isTrue(!DateUtils.isDateFormat(t.getCustomerPurchaseDate()),     "OC-01-001-01-15-006", "客户采购订单日期");
            }

            t.getOrderDetails().forEach(detail -> {
                AssertUtils.isWholeNumber(detail.getProductQuantity(),      true, "OC-01-001-01-15-006", "销售数量");
                AssertUtils.isNumber(detail.getStockConversionNum(),   true, "OC-01-001-01-15-006", "库存转换数量");
                AssertUtils.isNumber(detail.getUnitPrice(),            true, "OC-01-001-01-15-006", "常规单价");
                AssertUtils.isNumber(detail.getTotalAmount(),          true, "OC-01-001-01-15-006", "常规总金额");
                AssertUtils.isNumber(detail.getManualTotalAmount(),    false,"OC-01-001-01-15-006", "手工总金额");
                AssertUtils.isNumber(detail.getManualPrice(),          false,"OC-01-001-01-15-006", "手工单价");
                AssertUtils.isNumber(detail.getActivityPrice(),        false,"OC-01-001-01-15-006", "活动单价");
                AssertUtils.isNumber(detail.getActivityTotalAmount(),  false,"OC-01-001-01-15-006", "活动总金额");
                AssertUtils.isNumber(detail.getUnitConversionRelationship(),  false,"OC-01-001-01-15-006", "单位转换关系");

                AssertUtils.lengthCheck(detail.getSourceLineNum(),              10, true, "OC-01-001-01-15-004", "来源单行号");
                AssertUtils.lengthCheck(detail.getProductCode(),                50, true, "OC-01-001-01-15-004", "物料编码");
                AssertUtils.lengthCheck(detail.getProductName(),                50, true, "OC-01-001-01-15-004", "物料名称");
                AssertUtils.lengthCheck(detail.getProductQuantity(),            10, true, "OC-01-001-01-15-004", "销售数量");
                // AssertUtils.lengthCheck(detail.getStockConversionNum(),         10, true, "OC-01-001-01-15-004", "库存转换数量");
                AssertUtils.lengthCheck(detail.getSalesUnitCode(),              50, true, "OC-01-001-01-15-004", "销售单位编码");
                AssertUtils.lengthCheck(detail.getSalesUnitName(),              50, true, "OC-01-001-01-15-004", "销售单位名称");
                AssertUtils.lengthCheck(detail.getStockUnitCode(),              50, true, "OC-01-001-01-15-004", "库存单位编码");
                AssertUtils.lengthCheck(detail.getStockUnitName(),              50, true, "OC-01-001-01-15-004", "库存单位名称");
                AssertUtils.lengthCheck(detail.getUnitPrice(),                  10, true, "OC-01-001-01-15-004", "常规单价");
                AssertUtils.lengthCheck(detail.getTotalAmount().split("\\.")[0],                10, true, "OC-01-001-01-15-004", "常规总金额");
                AssertUtils.lengthCheck(detail.getUnitConversionRelationship(), 50, true, "OC-01-001-01-15-004", "单位转换关系");

                AssertUtils.isTrue(new BigDecimal("2147483647").compareTo(new BigDecimal(detail.getProductQuantity())) < 0, "OC-01-001-01-15-006", "销售数量", "最大2147483647");
                AssertUtils.isTrue(BigDecimal.ZERO.compareTo(new BigDecimal(detail.getProductQuantity())) >= 0,    "OC-01-001-01-15-006", "销售数量", "不允许为零或负数");
                AssertUtils.isTrue(BigDecimal.ZERO.compareTo(new BigDecimal(detail.getStockConversionNum())) >= 0, "OC-01-001-01-15-006", "库存转换数量", "不允许为零或负数");
                AssertUtils.isTrue(BigDecimal.ZERO.compareTo(new BigDecimal(detail.getUnitConversionRelationship())) >= 0, "OC-01-001-01-15-006", "单位转换关系", "不允许为零或负数");

                AssertUtils.lengthCheck(detail.getInnerProductCode(),           50, false, "OC-01-001-01-15-004", "产品编码");
                AssertUtils.lengthCheck(detail.getInnerProductName(),           50, false, "OC-01-001-01-15-004", "产品名称");
                AssertUtils.lengthCheck(detail.getProductBarCode(),             50, false, "OC-01-001-01-15-004", "产品条码");
                AssertUtils.lengthCheck(detail.getNote(),                      255, false, "OC-01-001-01-15-004", "订单行备注");
                AssertUtils.lengthCheck(detail.getActivityPrice(),              10, false, "OC-01-001-01-15-004", "活动单价");
                AssertUtils.lengthCheck(detail.getActivityTotalAmount(),        10, false, "OC-01-001-01-15-004", "活动总金额");
                AssertUtils.lengthCheck(detail.getActivityType(),               50, false, "OC-01-001-01-15-004", "活动类型");
                AssertUtils.lengthCheck(detail.getActivityId(),                 50, false, "OC-01-001-01-15-004", "活动ID");
                AssertUtils.lengthCheck(detail.getActivityLineNo(),             50, false, "OC-01-001-01-15-004", "活动项目号");
                AssertUtils.lengthCheck(detail.getGiftFlag(),                   50, false, "OC-01-001-01-15-004", "买赠标识");
                AssertUtils.lengthCheck(detail.getBuyItemNo(),                  50, false, "OC-01-001-01-15-004", "原品行号");
                AssertUtils.lengthCheck(detail.getManualTotalAmount(),          10, false, "OC-01-001-01-15-004", "手工总金额");
                AssertUtils.lengthCheck(detail.getManualPrice(),                10, false, "OC-01-001-01-15-004", "手工单价");

                AssertUtils.lengthCheck(detail.getShippingWarehouseCode(), 50, false, "OC-01-001-01-15-004", "逻辑仓库编码");
                AssertUtils.lengthCheck(detail.getShippingWarehouseName(), 50, false, "OC-01-001-01-15-004", "逻辑仓库名称");
                AssertUtils.lengthCheck(detail.getDeliveryFactoryCode(),   50, false, "OC-01-001-01-15-004", "交货工厂编码");
                AssertUtils.lengthCheck(detail.getDeliveryFactoryName(),   50, false, "OC-01-001-01-15-004", "交货工厂名称");
                AssertUtils.lengthCheck(detail.getStockCode(),             50, false, "OC-01-001-01-15-004", "库存地点编码");
                AssertUtils.lengthCheck(detail.getStockName(),             50, false, "OC-01-001-01-15-004", "库存地点名称");

                AssertUtils.lengthCheck(detail.getBizFeatures(), 1024, false, "OC-01-001-01-15-004", "扩展字段");

                // 金额参数 不允许为零或负数
                AssertUtils.moneyCheck(detail.getUnitPrice(),           true,  "OC-01-001-01-15-005", "常规单价");
                AssertUtils.moneyCheck(detail.getTotalAmount(),         true,  "OC-01-001-01-15-005", "常规总金额");
                AssertUtils.moneyCheck(detail.getManualTotalAmount(),   false, "OC-01-001-01-15-005", "手工总金额");
                AssertUtils.moneyCheck(detail.getManualPrice(),         false, "OC-01-001-01-15-005", "手工单价");
                AssertUtils.moneyCheck(detail.getActivityPrice(),       false, "OC-01-001-01-15-005", "活动单价");
                AssertUtils.moneyCheck(detail.getActivityTotalAmount(), false, "OC-01-001-01-15-005", "活动总金额");

                if (StringUtils.isNotBlank(detail.getActivityTotalAmount()) && StringUtils.isBlank(detail.getActivityPrice())) {
                    String activityPrice = new BigDecimal(detail.getActivityTotalAmount()).divide(new BigDecimal(detail.getProductQuantity()), RoundingMode.HALF_UP).toPlainString();
                    detail.setActivityPrice(activityPrice);
                }

                // 金额 NYC(元) 1.01 转 数据库(分) 101
                resetMoneyForNYC(detail);
            });
        });
    }

    /**
     * 金额转换 元转分
     * @param request
     */
    static void resetMoneyForNYC(SalesOrderAtomCreateLineRequest request) {
        request.setUnitPrice(MoneyUtils.moneyStrYuan2Fen(request.getUnitPrice()));
        request.setTotalAmount(MoneyUtils.moneyStrYuan2Fen(request.getTotalAmount()));
        request.setManualPrice(MoneyUtils.moneyStrYuan2Fen(request.getManualPrice()));
        request.setManualTotalAmount(MoneyUtils.moneyStrYuan2Fen(request.getManualTotalAmount()));
        request.setActivityPrice(MoneyUtils.moneyStrYuan2Fen(request.getActivityPrice()));
        request.setActivityTotalAmount(MoneyUtils.moneyStrYuan2Fen(request.getActivityTotalAmount()));
    }
}
